#ifndef TEMPLATE_COMPONENT_POLYGON_HPP_
# define TEMPLATE_COMPONENT_POLYGON_HPP_

# include <GL/gl.h>

# include "Abstract/Entity/AEntity.hpp"

# include "Class/Component/Coordinates.hpp"
# include "Class/Manager/Graphics.hpp"

namespace		SubEntity
{
  template<int unsigned vNbr = 3u, bool hasTex = true>
  class			Polygon: public Entity::AEntity
  {
  public:
	Polygon()
	  :	_Position(),
		_Texture()
	{
	}
	Polygon(Polygon const &pol)
	  :	_Position(),
		_Texture()
	{
	  this->_Initialize(pol);
	}

	Polygon const		&operator=(Polygon const &pol)
	{
	  if (this != &pol)
		this->_Initialize(pol);

	  return (*this);
	}

	static void			StartDraw() throw()
	{
	  if (vNbr == 2)
		glBegin(GL_LINES);
	  else if (vNbr == 4)
		glBegin(GL_QUADS);
	  else
		glBegin(GL_TRIANGLES);
	}
	static void			StopDraw() throw()
	{
	  glEnd();
	}

	virtual void		SetPosition(Component::Vector3f pos[vNbr])
	{
	  for (int unsigned i = 0 ; i < vNbr ; ++i)
		this->_Position[i] = pos[i];
	}
	virtual void		SetPosition(Component::Vector3f const &pos, int unsigned i)
	{
	  if (i < vNbr)
		this->_Position[i] = pos;
	}
	virtual void		SetTexturePosition(Component::Vector2f tex[vNbr])
	{
	  for (int unsigned i = 0 ; i < vNbr ; ++i)
		this->_Texture[i] = tex[i];
	}
	virtual void		SetTexturePosition(Component::Vector2f const &tex, int unsigned i)
	{
	  if (i < vNbr)
		this->_Texture[i] = tex;
	}
	virtual void		SetPolygon(Component::Vector3f pos[vNbr], Component::Vector2f tex[vNbr])
	{
	  this->SetPosition(pos);
	  this->SetTexturePosition(tex);
	}
	virtual void		SetPolygon(Component::Vector3f const &pos, Component::Vector2f const &tex, int unsigned i)
	{
	  this->SetPosition(pos, i);
	  this->SetTexturePosition(tex, i);
	}

	virtual void		Draw(Manager::Graphics const &)
	{
	  glColor3ub(255, 255, 255);
	  for (int unsigned i = 0 ; i < vNbr ; ++i)
		{
		  if (hasTex)
			glTexCoord2f(this->_Texture[i].x, this->_Texture[i].y);
		  glVertex3f(this->_Position[i].x, this->_Position[i].y, this->_Position[i].z);
		}
	}

	virtual ~Polygon() throw()
	{
	}


  protected:
	virtual void		_Initialize(Polygon const &pol)
	{
	  for (int unsigned i = 0 ; i < vNbr ; ++i)
		{
		  this->_Position[i] = pol._Position[i];
		  this->_Texture[i] = pol._Texture[i];
		}
	}


  protected:
	Component::Vector3f			_Position[vNbr];
	Component::Vector2f			_Texture[vNbr];
  };


  typedef Polygon<2, true>			Line3D;
  typedef Polygon<3, true>			Triangle3D;
  typedef Polygon<4, true>			Square3D;

  typedef Polygon<2, false>			SimpleLine3D;
  typedef Polygon<3, false>			SimpleTriangle3D;
  typedef Polygon<4, false>			SimpleSquare3D;
}

#endif
